/*------------------------------------------------------
*店铺网址：https://shop321633213.taobao.com
*作者：一叶孤沙
*日期：2020-11-24
*实验现象：车内有害气体检测
*QQ群：906015840
-------------------------------------------------------*/

#include "mid_cat1.h"
#include "usart.h"

static uint8_t cat1RxValue;

data_frame_t mid_cat1_data = { 0x00 };
static cat1_ctx_t cat1_ctx = { 0x00 };

void mid_cat1_ctx_register(cat1_ctx_t *ctx)
{
	cat1_ctx.recv_cb = ctx->recv_cb;
	cat1_ctx.status_cb = ctx->status_cb;
	cat1_ctx.status = ctx->status;
}

void mid_cat1_init(void)
{
	char ccid[24] = { 0x00 };
	
    drv_usart_init(2);  // USART3
    if (0 == drv_usart_recv_bytes_IT(2, &cat1RxValue, 1))
    {
        rt_kprintf("enable uart3 ISR\r\n");
    }
//	rt_thread_mdelay(30000);
	while (RT_EOK != mid_cat1_set_ate0() )
	{
		rt_kprintf("Send ATE0 Command Error\r\n");
		rt_thread_mdelay(1000);
	}
	rt_kprintf("Send ATE0 Command Success\r\n");
	rt_thread_mdelay(100);
	mid_cat1_get_ccid(ccid);
	rt_kprintf("get ccid is %s\r\n", ccid);
	rt_thread_mdelay(100);
	if ( RT_EOK == mid_cat1_get_ready_status() )
	{
		rt_kprintf("Module is ready!\r\n");
	}else
	{
		rt_kprintf("Module is not ready!\r\n");
	}
	rt_thread_mdelay(100);
	if (RT_EOK == mid_cat1_set_apn() )
	{
		rt_kprintf("Set APN success!\r\n");
	}
	rt_thread_mdelay(100);
	if (RT_EOK == mid_cat1_active_pdp() )
	{
	
		rt_kprintf("Active PDP success!\r\n");
	}
	rt_thread_mdelay(100);
	rt_kprintf("QOS is %d\r\n", mid_cat1_get_qos());
}

int mid_cat1_set_ate0(void)
{
	char cmd[24] = "ATE0\r\n";
	
	return mid_cat1_send_cmd (cmd, rt_strlen(cmd), RT_NULL, "OK", 3000);
}

int mid_cat1_get_imei(char *imei)
{
	char cmd[24] = "AT+CIMI\r\n";
	
	return mid_cat1_send_cmd (cmd, rt_strlen(cmd), RT_NULL, "OK", 3000);
}

int mid_cat1_get_ccid(char *ccid)
{
	rt_err_t ret = RT_EOK;
	char cmd[24] = "AT+CCID\r\n";
	
	ret = mid_cat1_send_cmd (cmd, rt_strlen(cmd), RT_NULL, "OK", 3000);
	sscanf((char *)mid_cat1_data.uart_recv_buff, "%*[^+]+CCID: %s\r\n", ccid);
	return ret;
}

int mid_cat1_get_ready_status(void)
{
	char cmd[24] = "AT+CPIN?\r\n";
	
	return mid_cat1_send_cmd (cmd, rt_strlen(cmd), RT_NULL, "OK", 3000);
}

int mid_cat1_set_apn(void)
{
	char cmd[64] = "AT+CGDCONT=1,\"IP\",\"CMIOT\"\r\n";
	
	return mid_cat1_send_cmd (cmd, rt_strlen(cmd), RT_NULL, "OK", 3000);
}

int mid_cat1_active_pdp(void)
{
	char cmd[64] = "AT+CGACT=1,1\r\n";
	
	return mid_cat1_send_cmd (cmd, rt_strlen(cmd), RT_NULL, "OK", 3000);
}

int mid_cat1_get_qos(void)
{
	int qos = 0, qos1 = 0;
	char cmd[64] = "AT+CSQ\r\n";
	
	if (RT_EOK == mid_cat1_send_cmd (cmd, rt_strlen(cmd), RT_NULL, "OK", 3000))
	{
		sscanf((char *)mid_cat1_data.uart_recv_buff, "%*[^+]+CSQ: %d,%d", &qos, &qos1);
	}
	
	return qos;
}


/**
 * @brief set transparent transmission mode
 * @param mode 0: transparent transmission mode, 1: command mode
 * @return 0:success, 1:error
 */
int mid_cat1_set_mode(uint8_t mode)
{
	return RT_EOK;
}

int mid_cat1_tcp_connect_server(uint8_t socket, char *ip, uint16_t port)
{
    return RT_EOK;
}

int mid_cat1_tcp_send(uint8_t socket, uint16_t len, uint8_t *data)
{
    return RT_EOK;
}

int mid_cat1_tcp_close(uint8_t socket)
{
    return RT_EOK;
}

int mid_cat1_mqtt_init(cat1_mqtt_params_t *params)
{
	char *cmd = "AT+MQTTCFG=\"106.55.124.154\",1883,\"RCNW9NF8X3861193040049653\",60,\"RCNW9NF8X3861193040049653;12010126;I0SEW;1922863220\",\"a4adb8afdec3891e53027b85b357f098a9c07c6d42db9418f71d2f6fd50e76c1;hmacsha256\",0,\"3.1.1\",0\r\n";
//	rt_sprintf(cmd, "AT+MQTTCFG=%s,%d,%s,%d,%s,%s,%d,%s,%d", params->host, params->port, params->client_id,
//				params->keepAlive, params->user_name, params->password, params->clean, params->version, params->encrypt);
	
//	rt_sprintf(cmd, "AT+MQTTCFG=\"%s\",%d,\"%s\",%d,\"%s\",\"a4adb8afdec3891e53027b85b357f098a9c07c6d42db9418f71d2f6fd50e76c1;hmacsha256\",0,\"3.1.1\",0\r\n", params->host, params->port, params->client_id,
//				params->keepAlive, params->user_name);
	rt_kprintf("cmd is %s\r\n", cmd);
	return mid_cat1_send_cmd (cmd, rt_strlen(cmd), RT_NULL, "OK", 5000);
}

/*
	AT+MQTTOPEN=1,1,0,0,0, "",""
	+MQTTOPEN:OK
	OK
*/
int mid_cat1_mqtt_start(void)
{
	char cmd[64] = "AT+MQTTOPEN=1,1,0,0,0,\"\",\"\"\r\n";
	
    return mid_cat1_send_cmd (cmd, rt_strlen(cmd), RT_NULL, "OK", 3000);
}

int mid_cat1_mqtt_get_status(void)
{
	char cmd[64] = "AT+MQTTSTAT?\r\n";
	int status = CAT1_STATUS_INIT;
	
    if (RT_EOK == mid_cat1_send_cmd (cmd, rt_strlen(cmd), RT_NULL, "OK", 3000))
	{
		sscanf((char *)mid_cat1_data.uart_recv_buff, "+MQTTSTAT:%d\r\nOK\r\n", &status);
		return status;
	}
	
	return 0;
}

int mid_cat1_mqtt_subscribe(char *topic, int qos)
{
	char cmd[64] = { 0x00 };
	
	rt_sprintf(cmd, "AT+MQTTSUB=\"%s\",%d\r\n", topic, qos);
	
    return mid_cat1_send_cmd (cmd, rt_strlen(cmd), RT_NULL, "OK", 3000);
}

int mid_cat1_mqtt_publish(char *topic, int qos, int retain, int dup, char *message )
{
	char cmd[256] = { 0x00 };
	
	rt_sprintf(cmd, "AT+MQTTPUB=\"%s\",%d,%d,%d,\"%s\"\r\n", topic, qos, retain, dup, message);
	
    return mid_cat1_send_cmd (cmd, rt_strlen(cmd), RT_NULL, "OK", 3000);
}

int mid_cat1_mqtt_disconnect(void)
{
	char cmd[64] = "AT+MQTTDISC";
	 
    return mid_cat1_send_cmd (cmd, rt_strlen(cmd), RT_NULL, "OK", 3000);
}

int mid_cat1_mqtt_auto_reconnect(int recon)
{
	char cmd[64] = { 0x00 };
	
	rt_sprintf(cmd, "AT+MQTTREC=%d\r\n", recon);
	
    return mid_cat1_send_cmd (cmd, rt_strlen(cmd), RT_NULL, "OK", 3000);
}

/**
 * @brief set overtime time, default overtime is 10s
 * @param time
 * @return if normal, 0 will be returned , otherwise, error type will be returned
 */
int mid_cat1_mqtt_overtime(int time)
{
    return RT_EOK;
}

/*
 * 函数名：ESP8266_Cmd
 * 描述  ：对WF-ESP8266模块发送AT指令
 * 输入  ：cmd，待发送的指令
 *         reply1，reply2，期待的响应，为NULL表不需响应，两者为或逻辑关系
 *         waittime，等待响应的时间
 * 返回  : 1，指令发送成功
 *         0，指令发送失败
 * 调用  ：被外部调用
 */
int mid_cat1_send_cmd (char * cmd, uint8_t cmd_len, char * reply1, char * reply2, uint32_t waittime)
{
    rt_memset(&mid_cat1_data, 0x00, sizeof(mid_cat1_data));
    drv_usart_send_bytes(2, (uint8_t *)cmd, cmd_len);

    if ( ( reply1 == 0 ) && ( reply2 == 0 ) )                      //不需要接收数据
        return RT_EINVAL;

    while (waittime)
    {
        if (1 == mid_cat1_data.full_packet)
        {
            break;
        }
        rt_thread_mdelay(1);
        waittime--;
    }

    if (0 != waittime)
    {
        if ( ( reply1 != 0 ) && ( reply2 != 0 ) )
		{
			if (rt_strstr ( (char *)mid_cat1_data.uart_recv_buff, reply1) || rt_strstr ( (char *)mid_cat1_data.uart_recv_buff, reply2))
				return RT_EOK;
			return RT_ERROR;
		}
        else if ( reply1 != 0 )
		{
			if (rt_strstr ( (char *)mid_cat1_data.uart_recv_buff, reply1))
				return RT_EOK;
			return RT_ERROR;
		}
        else
		{
			if (rt_strstr ( (char *)mid_cat1_data.uart_recv_buff, reply2))
				return RT_EOK;
			return RT_ERROR;
		}
    }else
    {
        rt_kprintf("AT CMD Error!\r\n");
		printf("recv :%s\r\n", mid_cat1_data.uart_recv_buff);
        return RT_ERROR;
    }
}

int mid_cat1_process_uart_recv_msg(void)
{
	int len = 0;
	char data_buff[128] = {0x00};
	
	mid_cat1_data.uart_recv_buff[mid_cat1_data.count++] = cat1RxValue;
	// \r\nOK\r\n
		if (0x0A == cat1RxValue)
		{
//			printf("recv .r\r\n");
			// 是否收到+MQTTPUBLISH:事件，该事件不会返回OK，需要额外处理
			if (rt_strstr((char *)mid_cat1_data.uart_recv_buff, "+MQTTPUBLISH:")){
//				printf("recv download command : %s\r\n", mid_cat1_data.uart_recv_buff);
//				+MQTTPUBLISH: 0,0,0,0,"$thing/down/property/RCNW9NF8X3/861193040049653",83,{"method":"control","clientToken":"clientToken-GYGrFk3UJ","params":{"Temp_Max":-6}}
				sscanf((char *)mid_cat1_data.uart_recv_buff, "%*[^$]$thing/down/property/RCNW9NF8X3/861193040049653\",%d,%s", &len, data_buff);
//				printf("recv cmd : %s(%d)\r\n", data_buff, len);
				if (cat1_ctx.recv_cb){
					cat1_ctx.recv_cb(data_buff, len);
					rt_memset(&mid_cat1_data, 0x00, sizeof(mid_cat1_data));
				}
			}else{
				drv_usart_recv_bytes(2, &cat1RxValue,1);
				mid_cat1_data.uart_recv_buff[mid_cat1_data.count++] = cat1RxValue;
				if ('O' == cat1RxValue){
					drv_usart_recv_bytes(2, &cat1RxValue,1);
					mid_cat1_data.uart_recv_buff[mid_cat1_data.count++] = cat1RxValue;
					if ('K' == cat1RxValue) {
////						drv_usart_recv_bytes(2, &cat1RxValue,1); // get '\r'
////						mid_cat1_data.uart_recv_buff[mid_cat1_data.count++] = cat1RxValue;
////						drv_usart_recv_bytes(2, &cat1RxValue,1); // get '\n'
////						mid_cat1_data.uart_recv_buff[mid_cat1_data.count++] = cat1RxValue;
						printf("recv a full packet : %s\r\n", mid_cat1_data.uart_recv_buff);
						mid_cat1_data.full_packet = 1;
						if (rt_strstr((char *)mid_cat1_data.uart_recv_buff, "+MQTTPINGRSP:")){
							cat1_ctx.status_cb(CAT1_STATU_PING);
							rt_memset(&mid_cat1_data, 0x00, sizeof(mid_cat1_data));
						}
					}
				}
			}
		}
		else if ('O' == cat1RxValue){
			drv_usart_recv_bytes(2, &cat1RxValue,1);
			mid_cat1_data.uart_recv_buff[mid_cat1_data.count++] = cat1RxValue;
			if ('K' == cat1RxValue) {
	////						drv_usart_recv_bytes(2, &cat1RxValue,1); // get '\r'
	////						mid_cat1_data.uart_recv_buff[mid_cat1_data.count++] = cat1RxValue;
	////						drv_usart_recv_bytes(2, &cat1RxValue,1); // get '\n'
	////						mid_cat1_data.uart_recv_buff[mid_cat1_data.count++] = cat1RxValue;
				printf("recv a full packet : %s\r\n", mid_cat1_data.uart_recv_buff);
				mid_cat1_data.full_packet = 1;
				if (rt_strstr((char *)mid_cat1_data.uart_recv_buff, "+MQTTPINGRSP:")){
					cat1_ctx.status_cb(CAT1_STATU_PING);
					rt_memset(&mid_cat1_data, 0x00, sizeof(mid_cat1_data));
				}
			}
		}

    drv_usart_recv_bytes_IT(2, &cat1RxValue, 1);

    return RT_EOK;
}

